import { computed, ref, watch, type ComputedRef, type Ref } from 'vue'
import { useDictStore, type OrgDictItem } from '@/store/dict'
import type { IGetDictsRes } from '@/api/system/dict/type'

/**
 * 字典返回类型
 * @description 将字典类型数组转换为带类型的对象，提供完整的字典管理功能
 * @template T - 字典类型数组
 */
type UseDictReturn<T extends readonly string[]> = {
	/** 响应式字典数据对象，每个字典都是 Ref */
	dicts: {
		[K in T[number]]: Ref<IGetDictsRes>
	}
	/** 是否正在加载 */
	loading: ComputedRef<boolean>
	/** 显式初始化方法 - 确保数据加载完成 */
	init: (force?: boolean) => Promise<void>
	/** 刷新所有字典 */
	refresh: () => Promise<void>
	/** 根据字典类型和值获取标签 */
	getLabel: (dictType: T[number], value: number | string) => string
	/** 通用字典查询方法 - 支持任意字典类型 */
	getDictLabel: (dictType: string, value: string | number | undefined) => string
	/** 注册单位查询 */
	getRegisterOrgLabel: (value: number | undefined) => string
	/** 在训单位查询 */
	getTrainOrgLabel: (value: number | undefined) => string
	/** 注册单位选项（响应式） */
	registerOrgOptions: ComputedRef<OrgDictItem[]>
	/** 在训单位选项（响应式） */
	trainOrgOptions: ComputedRef<OrgDictItem[]>
	/** 在训单位级联选项（响应式）- 用于级联选择器 */
	orgCascadeOptions: ComputedRef<any[]>
	/** 运动员在训单位：类型、级别级联（响应式） */
	trainOrgTypeLevelCascade: ComputedRef<any[]>
}

/**
 * 字典组合式函数
 *
 * @description 用于获取多个字典数据的响应式引用，提供完整的加载控制和状态管理
 *
 * @template T - 字典类型数组
 * @param dictTypes - 字典类型数组
 * @returns 包含字典数据、加载状态和控制方法的对象
 *
 * @example
 * ```typescript
 * // 基础使用
 * const { dicts, init, loading } = useDict(['sys_sys_user_sex', 'grade', 'gender'] as const)
 *
 * // 手动控制加载时机（推荐在表格场景）可以直接获取
 * const handleSearch = async () => {
 *   await init() // 确保字典数据加载完成
 *   const tableData = await getTableData()
 *   // 此时可以安全地进行字典映射
 * }
 *
 * // 使用字典数据（响应式）
 * options: dicts.sys_sys_user_sex  // Ref<IGetDictsRes>
 * options: dicts.grade             // Ref<IGetDictsRes>
 *
 * // 获取标签
 * const label = getLabel('grade', 1)
 * ```
 */
export function useDict<T extends readonly string[]>(dictTypes: string[]): UseDictReturn<T> {
	const dictStore = useDictStore()

	// 加载状态管理
	const loading = ref(false)

	// 创建响应式字典数据对象
	const dicts = {} as {
		[K in T[number]]: Ref<IGetDictsRes>
	}

	// 为每个字典类型创建响应式引用
	dictTypes.forEach(dictType => {
		// 创建 ref 存储字典数据
		dicts[dictType as T[number]] = ref(dictStore.getDict(dictType))

		// 监听 store 变化，自动更新字典数据（保持响应式）
		watch(
			() => dictStore.getDict(dictType),
			newValue => {
				dicts[dictType as T[number]].value = newValue
			},
			{ immediate: true }
		)
	})

	// 检查是否正在加载
	const isLoading = computed(() => loading.value)

	// 显式初始化方法
	const init = async (force: boolean = false) => {
		// 智能缓存：如果数据已存在且不强制，跳过
		if (!force && dictTypes.every(type => dictStore.getDict(type).length > 0)) {
			return
		}

		try {
			loading.value = true
			await dictStore.loadDicts(dictTypes as string[])
			// 响应式数据会通过 watch 自动更新
		} finally {
			loading.value = false
		}
	}

	// 刷新字典数据
	const refresh = async () => {
		// 清除缓存后重新加载
		dictTypes.forEach(dictType => {
			dictStore.clearDict(dictType)
		})
		await init(true)
	}

	// 获取字典项标签
	const getLabel = (dictType: T[number], value: number | string) => {
		const dict = dictStore.getDict(dictType)
		const item = dict.find(item => item.value === value)
		return item?.label || String(value)
	}

	// ============ 新增：通用字典查询方法 ============

	/**
	 * 通用字典查询方法 - 支持任意字典类型
	 * @param dictType 字典类型
	 * @param value 字典值
	 * @returns 字典标签
	 */
	const getDictLabel = (dictType: string, value: string | number | undefined): string => {
		if (value === undefined || value === null) return ''
		const list = dictStore.getDict(dictType)
		const item = list.find(d => String(d.value) === String(value))
		return item?.label || String(value)
	}

	// ============ 新增：组织字典功能（从 useOrgCascade 合并） ============

	// 响应式数据
	const registerOrgOptions = computed<OrgDictItem[]>(() => dictStore.getRegisterOrgs)
	const trainOrgOptions = computed<OrgDictItem[]>(() => dictStore.getTrainOrgs)
	// 级联选择器数据（用于 Cascader 组件）
	const orgCascadeOptions = computed(() => dictStore.getOrgCascade)

	/**
	 * 根据注册单位 ID 查找 label
	 * @param value 注册单位 ID - number 类型
	 * @returns label 字符串
	 */
	const getRegisterOrgLabel = (value: number | undefined): string => {
		if (!value) return ''
		const item = registerOrgOptions.value.find(item => Number(item.value) === Number(value))
		return item?.label || ''
	}

	/**
	 * 根据在训单位 ID 查找 label
	 * @param value 在训单位 ID - number 类型
	 * @returns label 字符串
	 */
	const getTrainOrgLabel = (value: number | undefined): string => {
		if (!value) return ''
		const item = trainOrgOptions.value.find(item => Number(item.value) === Number(value))
		return item?.label || ''
	}

	// 自动初始化（保持现有行为的兼容性）
	init()

	return {
		// ============ 原有功能 ============
		/** 响应式的字典数据对象 */
		dicts,
		/** 是否正在加载 */
		loading: isLoading,
		/** 显式初始化方法 - 确保数据加载完成 */
		init,
		/** 刷新所有字典 */
		refresh,
		/** 根据字典类型和值获取标签 */
		getLabel,

		// ============ 新增功能 ============
		/** 通用字典查询方法 - 支持任意字典类型 */
		getDictLabel,
		/** 注册单位查询 */
		getRegisterOrgLabel,
		/** 在训单位查询 */
		getTrainOrgLabel,
		/** 注册单位选项（响应式） */
		registerOrgOptions,
		/** 在训单位选项（响应式） */
		trainOrgOptions,
		/** 在训单位级联选项（响应式） */
		orgCascadeOptions,
		/** 运动员在训单位：类型、级别级联（响应式） */
		trainOrgTypeLevelCascade: computed(() => dictStore.getTrainOrgTypeLevelCascade)
	}
}
